package com.scalar.chiptrack.adaptor.asecl;

import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.users.VendorAdaptor;
import com.scalar.chiptrack.users.dao.AdaptorSetUpDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.DateUtil;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import HTTPClient.HTTPConnection;
import HTTPClient.HTTPResponse;
import HTTPClient.CookieModule;
import HTTPClient.NVPair;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Calendar;

/**
 * User: CHANDRA SEKHAR
 * Date: May 8, 2008
 * Time: 10:00:42 AM
 */
public class ASECLAdaptor extends JobHandler implements AdaptorConstants
{

    private static String HOST = "csweb.asecl.com.tw";
    private static int PORT = 80;

    //Login URI
    private static String FORM_LOGIN_ACTION = "/ASECL/uca2/login.do";
    //Turnkey URI's
    private static String FORM_TURNKEY_ACTION_1 = "/ASECL/ucb2_1/queryReport.do?authId=ucb2_1";
    private static String FORM_TURNKEY_ACTION_2 = "/ASECL/ucb2_1/listWIPResult.do";

    //Ship report URI's
    private static String FORM_SHIP_REPORT_ACTION_1 = "/ASECL/ucb2_12/queryReport.do?authId=ucb2_12";
    private static String FORM_SHIP_REPORT_ACTION_2 = "/ASECL/ucb2_12/listShipmentResult.do";
    
    //Logout URI
    private static String FORM_LOGOUT_ACTION = "/ASECL/uca2/logout.do";

    public static String FILE_NAME_TURNKEY_STATUS = "Turnkey_WIP_Report";
    public static String FILE_NAME_SHIP_STATUS    = "Shipment_Report";

    public static final String ADAPTOR_NAME = "ASECL_WIP";

    private Logger m_adaptorLogger  = null;
    private String m_dataOutputDir  = null;
    private String m_username       = null; //LENADMIN
    private String m_password       = null ;
    private String m_customerName   = null; //LEN
    private int    m_adaptor_id     = -1;

    public ASECLAdaptor() throws ScalarException
    {
        try
        {
           VendorAdaptor vendorAdaptor = AdaptorSetUpDAO.getVendorAdaptorDetailsByVendorNameAndLocation( VENDOR_NAME_ASECL, LOCATION_TYPE_ASSEMBLY );

            m_username = vendorAdaptor.getUserId().trim();
            m_password = vendorAdaptor.getPassWord().trim();
            m_customerName = vendorAdaptor.getCustomerId().trim();
            m_dataOutputDir = vendorAdaptor.getOutPutDirectory().trim();

            if ( m_dataOutputDir != null )
            {
                if ( m_dataOutputDir.endsWith( "/" ) || m_dataOutputDir.endsWith( "\\" ) )
                {
                    m_dataOutputDir = m_dataOutputDir + m_username;
                }
                else
                {
                    m_dataOutputDir = m_dataOutputDir + "/" + m_username;
                }

                AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
                m_adaptorLogger  =  AdaptorUtils.getAdaptorLogger( m_dataOutputDir, VENDOR_NAME_ASECL );
                AdaptorUtils.setLogger( m_adaptorLogger );
            }
        }
        catch ( ScalarException se )
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading ASECL Adaptor Username, Password details from database, Exception: " + se );
            throw se;
        }
    }

    public static void main( String[] args )  throws Exception
    {

        try
        {
            new ASECLAdaptor().execute();
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }

    public void execute() throws Exception
    {

        try
        {
            m_adaptor_id = AdaptorRunInfo.saveAdaptorLastUpdatedStatus( CONSTANT_ADAPTOR, ADAPTOR_NAME, CONSTANT_SUCCESS, -1);

            //Print the header details
            AdaptorUtils.printHeader(VENDOR_NAME_ASECL, CONSTANT_ADAPTOR);

            AdaptorUtils.removeOldFiles( m_dataOutputDir, m_adaptorLogger );

            //login to the Site
            HTTPConnection conn = login( HOST, PORT, m_username, m_password );

            if ( conn != null )
            {
                BufferedReader reader = null;
                //Request for Turn key wip status
                HTTPResponse rsp = requestTurnkeyReport( conn );
                if ( rsp != null )
                {
                    reader = new BufferedReader( new InputStreamReader( rsp.getInputStream() ) );
                    if ( reader != null )
                    {
                        System.out.println( "\tDownloading and saving the Turn Key Wip Report..." );
                        log( "\tDownloading and saving the Turn Key Wip Report..." );
                        AdaptorUtils.saveAsFile( reader , m_dataOutputDir, FILE_NAME_TURNKEY_STATUS , FILE_EXTN_CSV);
                        if ( m_adaptor_id > 0 )
                        {
                            AdaptorRunInfo.saveAdaptorFileInfo( m_adaptor_id , FILE_NAME_TURNKEY_STATUS, FILE_EXTN_CSV, StringUtils.formatDateandTime(DateUtil.getFormattedTimeStamp() )) ;
                        }
                    }
                    else
                    {
                        log( "Could not save Turn Key Wip Report from Buffer Reader" );
                        throw new ScalarException( "Could not save Turn Key Wip Report from Buffer Reader" );
                    }
                }
                else
                {
                    log( "Could not create response object of Turn Key Wip Report" );
                    throw new ScalarException( "Could not create response object of Turn Key Wip Report" );
                }

                //Request for Shipment Report
                rsp = requestShipmentReport( conn );
                if ( rsp != null )
                {
                    reader = new BufferedReader( new InputStreamReader( rsp.getInputStream() ) );
                    if ( reader != null )
                    {
                        System.out.println( "\tDownloading and saving the Shipment Report..." );
                        log( "\tDownloading and saving the Shipment Report..." );
                        AdaptorUtils.saveAsFile ( reader , m_dataOutputDir, FILE_NAME_SHIP_STATUS , FILE_EXTN_CSV);
                        if ( m_adaptor_id > 0 )
                        {
                            AdaptorRunInfo.saveAdaptorFileInfo( m_adaptor_id , FILE_NAME_SHIP_STATUS, FILE_EXTN_CSV, StringUtils.formatDateandTime(DateUtil.getFormattedTimeStamp() )) ;
                        }
                    }
                    else
                    {
                        log( "Could not save Shipment Report from Buffer Reader" );
                        throw new ScalarException( "Could not save Shipment Report from Buffer Reader" );
                    }
                }
                else
                {
                    log( "Could not create response object of Shipment Report" );
                    throw new ScalarException( "Could not create response object of Shipment Report" );
                }

                //logout from the site
                logout( conn );
                
                if ( reader != null )
                {
                    reader.close();
                    reader = null;
                }
            }
            else
            {
                log( "Could not able to get the Connection to ASECL web site" );
                throw new ScalarException( "Could not able to get the Connection to ASECL web site" );
            }
        }
        catch (Exception e )
        {
            AdaptorUtils.removeOldFiles( m_dataOutputDir, m_adaptorLogger);
            AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, m_adaptor_id );
            System.out.println("Exception while trying to connect and read data from "+HOST +" site: " + e);
            e.printStackTrace();
            throw e;
        }
    }

    private HTTPConnection login( String host, int port, String userId, String password ) throws Exception
    {

        HTTPConnection conn = null;

        conn = new HTTPConnection( host, port );

        NVPair defaultHeaders[] = new NVPair[6];
        defaultHeaders[0] = new NVPair( "Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*" );
        defaultHeaders[1] = new NVPair( "Referer", "http://" + host );
        defaultHeaders[2] = new NVPair( "Accept-Language", "hi" );
        defaultHeaders[3] = new NVPair( "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" );
        defaultHeaders[4] = new NVPair( "Host", host );
        defaultHeaders[5] = new NVPair( "Proxy-Connection", "Keep-Alive" );

        // Accept all cookies
        CookieModule.setCookiePolicyHandler( null );
        conn.addDefaultModule( CookieModule.class, -1 );
        conn.setDefaultHeaders( defaultHeaders );

        System.out.print( "Trying to login...." );
        log( "\nTrying to log in... " );

        HTTPResponse rsp = conn.Get( "/ASECL" );

        readData( rsp, 1 );

        NVPair[] formData = new NVPair[2];

        formData[0] = new NVPair( "account", userId );
        formData[1] = new NVPair( "password", password );

        rsp = conn.Post( FORM_LOGIN_ACTION, formData );
        readData( rsp, 1 );

        System.out.println( "done." );
        log( "done" );
        return conn;
    }
   /**
    *  To Log out from the ASECL site
    * @param conn
    * @throws Exception
    */
    private void logout( HTTPConnection conn ) throws Exception
    {
        System.out.print( "Submitting Request for logout......" );

        log( "\nSubmitting Request for logout...." );

        HTTPResponse rsp = conn.Get( FORM_LOGOUT_ACTION );
        readData( rsp, 1 );

        System.out.println( "done" );
        log( "done." );
    }
     /**
      * To get the ASECL Turnkey Status Assembly details sheet
      * @param conn
      * @return HTTPRespone
      * @throws Exception
      */
    private HTTPResponse requestTurnkeyReport( HTTPConnection conn ) throws Exception
    {

        HTTPResponse rsp = conn.Get( FORM_TURNKEY_ACTION_1 );
        //readData( rsp,1 );

        System.out.println( "Submitting request for Turnkey Report....." );

        NVPair[] formData = new NVPair[22];

        formData[0] = new NVPair("authId","ucb2_1");
        formData[1] = new NVPair( "statusStr", "" );
        formData[2] = new NVPair( "viewExcel", "no" );
        formData[3] = new NVPair( "groupColumnStr", "Lot Info;Basic Info;Device Info;Probe;Assembly Factory;Test Factory" );
        formData[4] = new NVPair( "CUST_ID", m_customerName );
        formData[5] = new NVPair( "PKG_TYPE", "" );
        formData[6] = new NVPair( "LEAD_CNT", "" );
        formData[7] = new NVPair( "DEVICE", "" );
        formData[8] = new NVPair( "WAFER_LOT", "" );
        formData[9] = new NVPair( "PO", "" );
        formData[10] = new NVPair( "STATUS", "A;D;R;C;W;P;T;F" );
        formData[11] = new NVPair( "showUnissue", "yes" );
        formData[12] = new NVPair( "reportType", "detail" );
        formData[13] = new NVPair( "menu1", "!DEVICE");
        formData[14] = new NVPair( "menu1", "!WAFER_LOT");
        formData[15] = new NVPair( "menu1", "!LOT_NO");
        formData[16] = new NVPair( "menu1", "!CONTROLLOT");
        formData[17] = new NVPair( "menu1", "!PO");
        formData[18] = new NVPair( "menu1", "!PKG_TYPE");
        formData[19] = new NVPair( "menu1", "!LEAD_CNT");
        formData[20] = new NVPair( "menu1", "!ASSY_SOD");
        formData[21] = new NVPair( "queryReport", "Query Report" );

        System.out.print( "\tReading intermediate information I...." );

        rsp = conn.Post( FORM_TURNKEY_ACTION_2, formData );

        //readData( rsp, 1 );

        NVPair[] tempFormData = new NVPair[9];

        tempFormData[0] = new NVPair( "viewExcel", "yes" );
        tempFormData[1] = new NVPair( "authId", "ucb2_1" );
        tempFormData[2] = new NVPair( "metadata", "CustEqualCondition@CS_WIP_TURNKEY!CUST_ID|1|LEN|Customer|Customer^EqualCondition@CS_WIP_TURNKEY!UNISS_PO|1|0|UNISS_PO|UNISS_PO^InCondition@CS_WIP_TURNKEY!STATUS|1|A;D;R;C;W;P;T;F|Product Type\nCUST_ID\n\nCS_WIP_TURNKEY!DEVICE;CS_WIP_TURNKEY!PKG_TYPE;CS_WIP_TURNKEY!LEAD_CNT\n1!CS_WIP_TURNKEY!REC_DATE\nCS_WIP_TURNKEY\n-1" );
        tempFormData[3] = new NVPair( "groupColumnStr", "Lot Info;Basic Info;Device Info;Probe;Assembly Factory;Test Factory" );
        tempFormData[4] = new NVPair( "columnGroupPreference", "LEN#ucb2_1#CS_WIP_TURNKEY#Lot Info;Basic Info;Device Info;Probe;Assembly Factory;Test Factory#CS_WIP_TURNKEYUNISS_PO" );
        tempFormData[5] = new NVPair( "pageSize", "15" );
        tempFormData[6] = new NVPair( "conditionStr", "");
        tempFormData[7] = new NVPair( "pNum", "1");
        tempFormData[8] = new NVPair( "btnVwXls", "View Excel" );

        rsp = conn.Post( FORM_TURNKEY_ACTION_2, tempFormData );
		//readData(rsp, 0 );

        System.out.println( "done" );

        return rsp;
    }
    /**
     *  To get the ASECl Assembly yield report response from site
     * @param //conn
     * @return HTTPResponse
     * @throws Exception
     */

    /*public HTTPResponse requestYieldReport( HTTPConnection conn ) throws Exception
    {

        System.out.print( "\nPassing through Yield Report intermediate screens ...." );

        HTTPResponse rsp = conn.Get( FORM_YIELD_REPORT_ACTION_1 );

        readData( rsp, 1 );

        System.out.println( "done" );


        Calendar begCal = Calendar.getInstance();
        Calendar endCal = Calendar.getInstance();
        begCal.add( Calendar.DAY_OF_MONTH, -15 );
        java.util.Date begDate = begCal.getTime();
        java.util.Date endDate = endCal.getTime();

        String begYear = StringUtils.formatDateToString( begDate, "yyyy" );
        String endYear = StringUtils.formatDateToString( endDate, "yyyy" );
        String begMonth = StringUtils.formatDateToString( begDate, "MM" );
        String endMonth = StringUtils.formatDateToString( endDate, "MM" );
        String begDay = StringUtils.formatDateToString( begDate, "dd" );
        String endDay = StringUtils.formatDateToString( endDate, "dd" );

        System.out.println( "Start Date " + StringUtils.formatDateToString( begDate, "MM/dd/yyyy" ) );
        System.out.println( "Stop Date " + StringUtils.formatDateToString( endDate, "MM/dd/yyyy" ) );

        System.out.println( "Submitting request for Yield Report....." );

        NVPair[] formData = new NVPair[21];
        //Hidden values
        formData[0] = new NVPair("authId","ucb2_6");
        formData[1] = new NVPair( "statusStr", "" );
        formData[2] = new NVPair( "viewExcel", "no" );

        formData[3] = new NVPair( "CUST_ID", m_customerName );
        //Yield Start Date
        formData[4] = new NVPair( "begyy", begYear );
        formData[5] = new NVPair( "begmm", begMonth );
        formData[6] = new NVPair( "begdd", begDay );
        //Yield End Date
        formData[7] = new NVPair( "ednyy", endYear );
        formData[8] = new NVPair( "endmm", endMonth );
        formData[9] = new NVPair( "enddd", endDay );

        formData[10] = new NVPair( "PKG_TYPE", "" );
        formData[11] = new NVPair( "LEAD_CNT", "" );
        formData[12] = new NVPair( "DEVICE", "" );
        formData[13] = new NVPair( "WAFER_LOT", "" );
        formData[14] = new NVPair( "TRACE_CODE", "" );
        formData[15] = new NVPair( "MARKLINE", "" );
        formData[16] = new NVPair( "reportType", "detail" );

        formData[17] = new NVPair( "menu1", "CS_YIELD!PKG_TYPE" );
        formData[18] = new NVPair( "menu1", "CS_YIELD!DEVICE" );
        formData[19] = new NVPair("menu1","CS_YIELD!WAFER_LOT");
        formData[20] = new NVPair( "button", "Query Report" );

        System.out.print( "\tReading intermediate information I...." );

        rsp = conn.Post( FORM_YIELD_REPORT_ACTION_2, formData );

        readData( rsp, 1 );

        System.out.println( "done" );

        System.out.print( "\tReading intermediate information II...." );
        System.out.println( "done" );
        System.out.print( "\nReading Yield Report in Excel format ...." );

        NVPair[] tempFormData = new NVPair[9];

        tempFormData[0] = new NVPair( "viewExcel", "yes" );
        tempFormData[1] = new NVPair( "authId", "ucb2_6" );
        tempFormData[2] = new NVPair( "metadata", "CustEqualCondition@CS_YIELD!CUST_ID|1|AIG|Customer|Customer^DateBetweenCondition@CS_YIELD!ASE_SHIP|3|"+begYear+begMonth+begDay +"|"+endYear+endMonth+endDay +"|Yield|Start Date|Stop Date\r\nCUST_ID\r\n\r\n\r\n|3!CS_YIELD!ASE_SHIP\r\nCS_YIELD\r\n-1");
        tempFormData[3] = new NVPair( "pageSize", "15" );
        tempFormData[4] = new NVPair( "conditionStr", "");
        tempFormData[5] = new NVPair( "dateType", "");
        tempFormData[6] = new NVPair( "chartType", "linechart");
        tempFormData[7] = new NVPair( "pNum", "1");
        tempFormData[8] = new NVPair( "btnVwXls", "View Excel" );

        rsp = conn.Post( FORM_YIELD_REPORT_ACTION_2, tempFormData );
        //readData(rsp, 1);
        System.out.println( "done" );

        return rsp;
    }*/

    public HTTPResponse requestShipmentReport( HTTPConnection conn ) throws Exception
    {
                
        HTTPResponse rsp = conn.Get( FORM_SHIP_REPORT_ACTION_1 );

        //readData( rsp, 1 );

        Calendar beginCal = Calendar.getInstance();
        Calendar endCal = Calendar.getInstance();
        beginCal.add( Calendar.DAY_OF_MONTH, -15 );

        String beginYear = beginCal.get( Calendar.YEAR ) + "";
        String beginMonth = ( beginCal.get( Calendar.MONTH ) + 1 ) + "";
        if ( beginMonth.length() == 1 )
        {
            beginMonth = "0" + beginMonth;
        }

        String beginDay = beginCal.get( Calendar.DAY_OF_MONTH ) + "";
        if ( beginDay.length() == 1 )
        {
            beginDay = "0" + beginDay;
        }

        String endYear = endCal.get( Calendar.YEAR ) + "";
        String endMonth = ( endCal.get( Calendar.MONTH ) + 1 ) + "";
        if ( endMonth.length() == 1 )
        {
            endMonth = "0" + endMonth;
        }

        String endDay = endCal.get( Calendar.DAY_OF_MONTH ) + "";
        if ( endDay.length() == 1 )
        {
            endDay = "0" + endDay;
        }

        //System.out.println( "Begining date = " + beginYear + "/" + beginMonth + "/" + beginDay );
        //System.out.println( "End date = " + endYear + "/" + endMonth + "/" + endDay );

        System.out.println( "Submitting request for Shipment Report....." );

        NVPair[] formData = new NVPair[20];

        formData[0] = new NVPair("authId","ucb2_12");
        formData[1] = new NVPair( "statusStr", "" );
        formData[2] = new NVPair( "viewExcel", "no" );

        formData[3] = new NVPair( "CUST_ID", m_customerName );
        formData[4] = new NVPair( "begyy", beginYear );
        formData[5] = new NVPair( "begmm", beginMonth );
        formData[6] = new NVPair( "begdd", beginDay );
        formData[7] = new NVPair( "ednyy", endYear );
        formData[8] = new NVPair( "endmm", endMonth );
        formData[9] = new NVPair( "endedd", endDay );
        formData[10] = new NVPair( "PKG_TYPE", "" );
        formData[11] = new NVPair( "WAFER_LOT", "" );
        formData[12] = new NVPair( "DEVICE2", "" );
        formData[12] = new NVPair( "RELEASE", "" );
        formData[13] = new NVPair( "INV_NO", "" );
        formData[14] = new NVPair( "SHP_TO_4", "" );
        formData[15] = new NVPair( "reportType", "detail" );
        formData[16] = new NVPair( "menu1", "VW_CS_SHIP!PKG_TYPE" );
        formData[17] = new NVPair( "menu1", "VW_CS_SHIP!DEVICE" );
        formData[18] = new NVPair( "menu1", "VW_CS_SHIP!WAFER_LOT" );
        formData[19] = new NVPair( "button", "Query Report" );

        System.out.print( "\tReading intermediate information I...." );

        rsp = conn.Post( FORM_SHIP_REPORT_ACTION_2, formData );
        //readData( rsp, 1 );

        System.out.println( "done" );

        NVPair[] tempFormData = new NVPair[8];

        tempFormData[0] = new NVPair( "viewExcel", "yes" );
        tempFormData[1] = new NVPair( "authId", "ucb2_12" );
        tempFormData[2] = new NVPair( "metadata", "CustEqualCondition@VW_CS_SHIP!CUST_ID|1|LEN|Customer|Customer^DateBetweenCondition@VW_CS_SHIP!SHP_OUT_DATE|3|"+beginYear+beginMonth+beginDay +"|"+endYear+endMonth+endDay +"|Shipment|Start Date|Stop Date\r\nCUST_ID\r\n\r\n\r\n|3!VW_CS_SHIP!SHP_OUT_DATE\r\nVW_CS_SHIP\r\n-1");
        tempFormData[3] = new NVPair( "pageSize", "15" );
        tempFormData[4] = new NVPair( "conditionStr", "");
        tempFormData[5] = new NVPair( "chartStr", "");
        tempFormData[6] = new NVPair( "dropdownPage1", "1");
        tempFormData[7] = new NVPair( "button3", "View Excel" );

        rsp = conn.Post( FORM_SHIP_REPORT_ACTION_2, tempFormData );
        //readData(rsp, 0);
                
        return rsp;
    }

    public void readData( HTTPResponse rsp, int debug ) throws Exception
    {

        byte[] data = new byte[1024];
        while ( rsp.getInputStream().read( data ) != -1 )
        {
            if ( debug == 0 )
            {
                System.out.println( new String( data ) );
            }
        }
    }

    private void log( String message )
    {

        if ( message == null ) return;

        if ( m_adaptorLogger != null )
        {
            synchronized ( m_adaptorLogger )
            {
                m_adaptorLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
}
